﻿#pragma once

#define _USE_MATH_DEFINES
#include "../MirObjects/Effect.h"
#include "../MirControls/MirScene.h"
#include "../MirObjects/UserObject.h"
#include "Dialogs/MainDialogs.h"
#include "Dialogs/NPCDialogs.h"
#include "Dialogs/HelpDialog.h"
#include "Dialogs/MountDialog.h"
#include "Dialogs/FishingDialog.h"
#include "Dialogs/GroupDialog.h"
#include "Dialogs/GuildDialog.h"
#include "Dialogs/TrustMerchantDialog.h"
#include "Dialogs/TradeDialogs.h"
#include "Dialogs/SocketDialog.h"
#include "Dialogs/ChatOptionDialog.h"
#include "Dialogs/ChatNoticeDialog.h"
#include "Dialogs/QuestDialogs.h"
#include "Dialogs/RankingDialog.h"
#include "Dialogs/MailDialogs.h"
#include "Dialogs/IntelligentCreatureDialogs.h"
#include "Dialogs/FriendDialog.h"
#include "Dialogs/RelationshipDialog.h"
#include "Dialogs/MentorDialog.h"
#include "Dialogs/GameshopDialog.h"
#include "Dialogs/ReportDialog.h"
#include "Dialogs/ItemRentingDialog.h"
#include "Dialogs/ItemRentDialog.h"
#include "Dialogs/ItemRentalDialog.h"
#include "Dialogs/BuffDialog.h"
#include "Dialogs/KeyboardLayoutDialog.h"
#include "Dialogs/NoticeDialog.h"
#include "Dialogs/TimerDialog.h"
#include "Dialogs/CompassDialog.h"
#include "../../Shared/Data/ItemData.h"
#include "../../Shared/Data/ClientData.h"
#include "../MirControls/MirItemCell.h"
#include "../MirControls/MirControl.h"
#include "../../Shared/Enums.h"
#include "../MirControls/MirLabel.h"
#include "../../Shared/Packet.h"
#include "../../Shared/ServerPackets.h"
#include "../../Shared/Data/GuildData.h"
#include "../MirObjects/MapObject.h"
#include "../MirObjects/MapCode.h"
#include "../../Shared/Data/SharedData.h"
#include <string>
#include <vector>
#include <algorithm>
#include <cmath>
#include <stdexcept>
#include <any>
#include <optional>
#include "../../stringhelper.h"
#include "../../tangible_filesystem.h"

//C# TO C++ CONVERTER NOTE: Forward class declarations:
namespace Client::MirScenes { class MapControl; }
namespace Client::MirScenes { class UserId; }
namespace Client::MirScenes { class OutPutMessage; }

using namespace Client::MirControls;
using namespace Client::MirGraphics;
using namespace Client::MirNetwork;
using namespace Client::MirObjects;
using namespace Client::MirSounds;
using namespace SlimDX;
using namespace SlimDX::Direct3D9;
//C# TO C++ CONVERTER TODO TASK: C# to C++ Converter could not confirm whether this is a namespace alias or a type alias:
//using Font = System::Drawing::Font;
namespace S = ServerPackets;
namespace C = ClientPackets;
using Effect = Client::MirObjects::Effect;

using namespace Client::MirScenes::Dialogs;
using namespace Client::Utils;

namespace Client::MirScenes
{
    class GameScene final : public MirScene
    {
    public:
        static GameScene *Scene;

        virtual ~GameScene()
        {
            delete MapControl;
            delete MainDialog;
            delete ChatDialog;
            delete ChatControl;
            delete InventoryDialog;
            delete CharacterDialog;
            delete CraftDialog;
            delete StorageDialog;
            delete BeltDialog;
            delete MiniMapDialog;
            delete InspectDialog;
            delete OptionDialog;
            delete MenuDialog;
            delete NPCDialog;
            delete NPCGoodsDialog;
            delete NPCSubGoodsDialog;
            delete NPCCraftGoodsDialog;
            delete NPCDropDialog;
            delete NPCAwakeDialog;
            delete HelpDialog;
            delete MountDialog;
            delete FishingDialog;
            delete FishingStatusDialog;
            delete RefineDialog;
            delete GroupDialog;
            delete GuildDialog;
            delete BigMapDialog;
            delete TrustMerchantDialog;
            delete CharacterDuraPanel;
            delete DuraStatusPanel;
            delete TradeDialog;
            delete GuestTradeDialog;
            delete CustomPanel1;
            delete SocketDialog;
            delete ChatOptionDialog;
            delete ChatNoticeDialog;
            delete QuestListDialog;
            delete QuestDetailDialog;
            delete QuestLogDialog;
            delete QuestTrackingDialog;
            delete RankingDialog;
            delete MailListDialog;
            delete MailComposeLetterDialog;
            delete MailComposeParcelDialog;
            delete MailReadLetterDialog;
            delete MailReadParcelDialog;
            delete IntelligentCreatureDialog;
            delete IntelligentCreatureOptionsDialog;
            delete IntelligentCreatureOptionsGradeDialog;
            delete FriendDialog;
            delete MemoDialog;
            delete RelationshipDialog;
            delete MentorDialog;
            delete GameShopDialog;
            delete ReportDialog;
            delete ItemRentingDialog;
            delete ItemRentDialog;
            delete GuestItemRentingDialog;
            delete GuestItemRentDialog;
            delete ItemRentalDialog;
            delete BuffsDialog;
            delete KeyboardLayoutDialog;
            delete NoticeDialog;
            delete TimerControl;
            delete CompassControl;
            delete ItemLabel;
            delete MailLabel;
            delete MemoLabel;
            delete GuildBuffLabel;
        }

        static UserObject *getUser();
        static void setUser(UserObject *value);

        static long long MoveTime;
        static long long AttackTime;
        static long long NextRunTime;
        static long long LogTime;
        static long long LastRunTime;
        static bool CanMove;
        static bool CanRun;

        MapControl *MapControl;
        MainDialog *MainDialog;
        ChatDialog *ChatDialog;
        ChatControlBar *ChatControl;
        InventoryDialog *InventoryDialog;
        CharacterDialog *CharacterDialog;
        CraftDialog *CraftDialog;
        StorageDialog *StorageDialog;
        BeltDialog *BeltDialog;
        MiniMapDialog *MiniMapDialog;
        InspectDialog *InspectDialog;
        OptionDialog *OptionDialog;
        MenuDialog *MenuDialog;
        NPCDialog *NPCDialog;
        NPCGoodsDialog *NPCGoodsDialog;
        NPCGoodsDialog *NPCSubGoodsDialog;
        NPCGoodsDialog *NPCCraftGoodsDialog;
        NPCDropDialog *NPCDropDialog;
        NPCAwakeDialog *NPCAwakeDialog;
        HelpDialog *HelpDialog;
        MountDialog *MountDialog;
        FishingDialog *FishingDialog;
        FishingStatusDialog *FishingStatusDialog;
        RefineDialog *RefineDialog;

        GroupDialog *GroupDialog;
        GuildDialog *GuildDialog;

        BigMapDialog *BigMapDialog;
        TrustMerchantDialog *TrustMerchantDialog;
        CharacterDuraPanel *CharacterDuraPanel;
        DuraStatusDialog *DuraStatusPanel;
        TradeDialog *TradeDialog;
        GuestTradeDialog *GuestTradeDialog;

        CustomPanel1 *CustomPanel1;
        SocketDialog *SocketDialog;

        std::vector<SkillBarDialog*> SkillBarDialogs;
        ChatOptionDialog *ChatOptionDialog;
        ChatNoticeDialog *ChatNoticeDialog;

        QuestListDialog *QuestListDialog;
        QuestDetailDialog *QuestDetailDialog;
        QuestDiaryDialog *QuestLogDialog;
        QuestTrackingDialog *QuestTrackingDialog;

        RankingDialog *RankingDialog;

        MailListDialog *MailListDialog;
        MailComposeLetterDialog *MailComposeLetterDialog;
        MailComposeParcelDialog *MailComposeParcelDialog;
        MailReadLetterDialog *MailReadLetterDialog;
        MailReadParcelDialog *MailReadParcelDialog;

        IntelligentCreatureDialog *IntelligentCreatureDialog;
        IntelligentCreatureOptionsDialog *IntelligentCreatureOptionsDialog;
        IntelligentCreatureOptionsGradeDialog *IntelligentCreatureOptionsGradeDialog;

        FriendDialog *FriendDialog;
        MemoDialog *MemoDialog;
        RelationshipDialog *RelationshipDialog;
        MentorDialog *MentorDialog;
        GameShopDialog *GameShopDialog;

        ReportDialog *ReportDialog;

        ItemRentingDialog *ItemRentingDialog;
        ItemRentDialog *ItemRentDialog;
        GuestItemRentingDialog *GuestItemRentingDialog;
        GuestItemRentDialog *GuestItemRentDialog;
        ItemRentalDialog *ItemRentalDialog;

        BuffDialog *BuffsDialog;

        KeyboardLayoutDialog *KeyboardLayoutDialog;
        NoticeDialog *NoticeDialog;

        TimerDialog *TimerControl;
        CompassDialog *CompassControl;


        static std::vector<ItemInfo*> ItemInfoList;
        static std::vector<UserId*> UserIdList;
        static std::vector<UserItem*> ChatItemList;
        static std::vector<ClientQuestInfo*> QuestInfoList;
        static std::vector<GameShopItem*> GameShopInfoList;
        static std::vector<ClientRecipeInfo*> RecipeInfoList;

        std::vector<ClientBuff*> Buffs;

        static std::vector<UserItem*> Storage;
        static std::vector<UserItem*> GuildStorage;
        static std::vector<UserItem*> Refine;
        static UserItem *HoverItem;
        static UserItem *SelectedItem;
        static MirItemCell *SelectedCell;

        static bool PickedUpGold;
        MirControl *ItemLabel, *MailLabel, *MemoLabel, *GuildBuffLabel;
        static long long UseItemTime;
        static long long PickUpTime;
        static long long DropViewTime;
        static long long TargetDeadTime;
        static unsigned int Gold;
        static unsigned int Credit;
        static long long InspectTime;
        bool ShowReviveMessage = false;


        bool NewMail = false;
        int NewMailCounter = 0;


        AttackMode AMode = static_cast<AttackMode>(0);
        PetMode PMode = static_cast<PetMode>(0);
        LightSetting Lights = static_cast<LightSetting>(0);

        static long long NPCTime;
        static unsigned int NPCID;
        static float NPCRate;
        static unsigned int DefaultNPCID;
        static bool HideAddedStoreStats;

        long long ToggleTime = 0;
        static bool Slaying;
        static bool Thrusting;
        static bool HalfMoon;
        static bool CrossHalfMoon;
        static bool DoubleSlash;
        static bool TwinDrakeBlade;
        static bool FlamingSword;
        static long long SpellTime;

        std::vector<MirLabel*> OutputLines(10);
        std::vector<OutPutMessage*> OutputMessages;

        long long OutputDelay = 0;

        GameScene();

    private:
        void UpdateMouseCursor();

    public:
        void OutputMessage(const std::string &message, OutputMessageType type = OutputMessageType::Normal);

    private:
        void ProcessOuput();
        void GameScene_KeyDown(std::any sender, KeyEventArgs *e);

    public:
        void ChangeSkillMode(std::optional<bool> &ctrl);

        void ChangePetMode();

        void ChangeAttackMode();

        void UseSpell(int key);

        void QuitGame();
        void LogOut();

    protected:
        void DrawControl() override;
    public:
        void Process() override;

        void DialogProcess();

        void ProcessPacket(Packet *p) override;

    private:
        void KeepAlive(S::KeepAlive *p);
        void MapInformation(S::MapInformation *p);
        void UserInformation(S::UserInformation *p);
        void UserSlotsRefresh(S::UserSlotsRefresh *p);

        void UserLocation(S::UserLocation *p);
        void ReceiveChat(S::Chat *p);
        void ObjectPlayer(S::ObjectPlayer *p);
        void ObjectRemove(S::ObjectRemove *p);
        void ObjectTurn(S::ObjectTurn *p);
        void ObjectWalk(S::ObjectWalk *p);
        void ObjectRun(S::ObjectRun *p);
        void ObjectChat(S::ObjectChat *p);
        void MoveItem(S::MoveItem *p);
        void EquipItem(S::EquipItem *p);
        void EquipSlotItem(S::EquipSlotItem *p);

        void CombineItem(S::CombineItem *p);

        void MergeItem(S::MergeItem *p);
        void RemoveItem(S::RemoveItem *p);
        void RemoveSlotItem(S::RemoveSlotItem *p);
        void TakeBackItem(S::TakeBackItem *p);
        void StoreItem(S::StoreItem *p);
        void DepositRefineItem(S::DepositRefineItem *p);

        void RetrieveRefineItem(S::RetrieveRefineItem *p);

        void RefineCancel(S::RefineCancel *p);

        void RefineItem(S::RefineItem *p);


        void DepositTradeItem(S::DepositTradeItem *p);
        void RetrieveTradeItem(S::RetrieveTradeItem *p);
        void SplitItem(S::SplitItem *p);

        void SplitItem1(S::SplitItem1 *p);
        void UseItem(S::UseItem *p);
        void DropItem(S::DropItem *p);


        void MountUpdate(S::MountUpdate *p);

        void TransformUpdate(S::TransformUpdate *p);

        void FishingUpdate(S::FishingUpdate *p);

        void CompleteQuest(S::CompleteQuest *p);

        void ShareQuest(S::ShareQuest *p);

        void ChangeQuest(S::ChangeQuest *p);

        void PlayerUpdate(S::PlayerUpdate *p);
        void PlayerInspect(S::PlayerInspect *p);
        void LogOutSuccess(S::LogOutSuccess *p);
        void LogOutFailed(S::LogOutFailed *p);

        void TimeOfDay(S::TimeOfDay *p);
        void ChangeAMode(S::ChangeAMode *p);
        void ChangePMode(S::ChangePMode *p);

        void ObjectItem(S::ObjectItem *p);
        void ObjectGold(S::ObjectGold *p);
        void GainedItem(S::GainedItem *p);
        void GainedQuestItem(S::GainedQuestItem *p);

        void GainedGold(S::GainedGold *p);
        void LoseGold(S::LoseGold *p);
        void GainedCredit(S::GainedCredit *p);
        void LoseCredit(S::LoseCredit *p);
        void ObjectMonster(S::ObjectMonster *p);
        void ObjectAttack(S::ObjectAttack *p);
        void Struck(S::Struck *p);
        void ObjectStruck(S::ObjectStruck *p);

        void DamageIndicator(S::DamageIndicator *p);

        void DuraChanged(S::DuraChanged *p);
        void HealthChanged(S::HealthChanged *p);

        void DeleteQuestItem(S::DeleteQuestItem *p);

        void DeleteItem(S::DeleteItem *p);
        void Death(S::Death *p);
        void ObjectDied(S::ObjectDied *p);
        void ColourChanged(S::ColourChanged *p);
        void ObjectColourChanged(S::ObjectColourChanged *p);

        void ObjectGuildNameChanged(S::ObjectGuildNameChanged *p);
        void GainExperience(S::GainExperience *p);
        void LevelChanged(S::LevelChanged *p);
        void ObjectLeveled(S::ObjectLeveled *p);
        void ObjectHarvest(S::ObjectHarvest *p);
        void ObjectHarvested(S::ObjectHarvested *p);
        void ObjectNPC(S::ObjectNPC *p);
        void NPCResponse(S::NPCResponse *p);

        void NPCUpdate(S::NPCUpdate *p);

        void NPCImageUpdate(S::NPCImageUpdate *p);
        void DefaultNPC(S::DefaultNPC *p);


        void ObjectHide(S::ObjectHide *p);
        void ObjectShow(S::ObjectShow *p);
        void Poisoned(S::Poisoned *p);
        void ObjectPoisoned(S::ObjectPoisoned *p);
        void MapChanged(S::MapChanged *p);
        void ObjectTeleportOut(S::ObjectTeleportOut *p);
        void ObjectTeleportIn(S::ObjectTeleportIn *p);
        void TeleportIn();
        void NPCGoods(S::NPCGoods *p);
        void NPCPearlGoods(S::NPCPearlGoods *p);

        void NPCSell();
        void NPCRepair(S::NPCRepair *p);
        void NPCStorage();
        void NPCRequestInput(S::NPCRequestInput *p);

        void NPCSRepair(S::NPCSRepair *p);

        void NPCRefine(S::NPCRefine *p);

        void NPCCheckRefine(S::NPCCheckRefine *p);

        void NPCCollectRefine(S::NPCCollectRefine *p);

        void NPCReplaceWedRing(S::NPCReplaceWedRing *p);


        void SellItem(S::SellItem *p);
        void RepairItem(S::RepairItem *p);
        void CraftItem(S::CraftItem *p);
        void ItemRepaired(S::ItemRepaired *p);

        void ItemSlotSizeChanged(S::ItemSlotSizeChanged *p);

        void ItemUpgraded(S::ItemUpgraded *p);

        void NewMagic(S::NewMagic *p);

        void RemoveMagic(S::RemoveMagic *p);

        void MagicLeveled(S::MagicLeveled *p);
        void Magic(S::Magic *p);

        void MagicDelay(S::MagicDelay *p);

        void MagicCast(S::MagicCast *p);

        void ObjectMagic(S::ObjectMagic *p);

        void ObjectProjectile(S::ObjectProjectile *p);

        void ObjectEffect(S::ObjectEffect *p);

        void RangeAttack(S::RangeAttack *p);

        void Pushed(S::Pushed *p);

        void ObjectPushed(S::ObjectPushed *p);

        void ObjectName(S::ObjectName *p);
        void UserStorage(S::UserStorage *p);
        void SwitchGroup(S::SwitchGroup *p);

        void DeleteGroup();

        void DeleteMember(S::DeleteMember *p);

        void GroupInvite(S::GroupInvite *p);
        void AddMember(S::AddMember *p);
        void Revived();
        void ObjectRevived(S::ObjectRevived *p);
        void SpellToggle(S::SpellToggle *p);

        void ObjectHealth(S::ObjectHealth *p);

        void MapEffect(S::MapEffect *p);

        void ObjectRangeAttack(S::ObjectRangeAttack *p);

        void AddBuff(S::AddBuff *p);

        void RemoveBuff(S::RemoveBuff *p);

        void ObjectHidden(S::ObjectHidden *p);

        void ObjectSneaking(S::ObjectSneaking *p);

        void ObjectLevelEffects(S::ObjectLevelEffects *p);

        void RefreshItem(S::RefreshItem *p);

        void ObjectSpell(S::ObjectSpell *p);

        void ObjectDeco(S::ObjectDeco *p);

        void UserDash(S::UserDash *p);

        void UserDashFail(S::UserDashFail *p);

        void ObjectDash(S::ObjectDash *p);

        void ObjectDashFail(S::ObjectDashFail *p);

        void UserBackStep(S::UserBackStep *p);

        void ObjectBackStep(S::ObjectBackStep *p);

        void UserDashAttack(S::UserDashAttack *p);

        void ObjectDashAttack(S::ObjectDashAttack *p);

        void UserAttackMove(S::UserAttackMove *p); //Warrior Skill - SlashingBurst

        void SetConcentration(S::SetConcentration *p);

        void SetElemental(S::SetElemental *p);

        void RemoveDelayedExplosion(S::RemoveDelayedExplosion *p);

        void SetBindingShot(S::SetBindingShot *p);

        void SendOutputMessage(S::SendOutputMessage *p);

        void NPCConsign();
        void NPCMarket(S::NPCMarket *p);
        void NPCMarketPage(S::NPCMarketPage *p);
        void ConsignItem(S::ConsignItem *p);
        void MarketFail(S::MarketFail *p);
        void MarketSuccess(S::MarketSuccess *p);
        void ObjectSitDown(S::ObjectSitDown *p);

        void BaseStatsInfo(S::BaseStatsInfo *p);

        void UserName(S::UserName *p);

        void ChatItemStats(S::ChatItemStats *p);

        void GuildInvite(S::GuildInvite *p);

        void GuildNameRequest(S::GuildNameRequest *p);

        void GuildRequestWar(S::GuildRequestWar *p);

        void GuildNoticeChange(S::GuildNoticeChange *p);
        void GuildMemberChange(S::GuildMemberChange *p);

        void GuildStatus(S::GuildStatus *p);

        void GuildExpGain(S::GuildExpGain *p);

        void GuildStorageGoldChange(S::GuildStorageGoldChange *p);

        void GuildStorageItemChange(S::GuildStorageItemChange *p);
        void GuildStorageList(S::GuildStorageList *p);

        void MarriageRequest(S::MarriageRequest *p);

        void DivorceRequest(S::DivorceRequest *p);

        void MentorRequest(S::MentorRequest *p);

        bool UpdateGuildBuff(GuildBuff *buff, bool Remove = false);

        void GuildBuffList(S::GuildBuffList *p);

        void TradeRequest(S::TradeRequest *p);
        void TradeAccept(S::TradeAccept *p);
        void TradeGold(S::TradeGold *p);
        void TradeItem(S::TradeItem *p);
        void TradeConfirm();
        void TradeCancel(S::TradeCancel *p);
        void NPCAwakening();
        void NPCDisassemble();
        void NPCDowngrade();
        void NPCReset();
        void AwakeningNeedMaterials(S::AwakeningNeedMaterials *p);
        void AwakeningLockedItem(S::AwakeningLockedItem *p);
        void Awakening(S::Awakening *p);

        void ReceiveMail(S::ReceiveMail *p);

        void MailLockedItem(S::MailLockedItem *p);

        void MailSendRequest(S::MailSendRequest *p);

        void MailSent(S::MailSent *p);

        void ParcelCollected(S::ParcelCollected *p);

        void ResizeInventory(S::ResizeInventory *p);

        void ResizeStorage(S::ResizeStorage *p);

        void MailCost(S::MailCost *p);

    public:
        void AddQuestItem(UserItem *item);

    private:
        void RequestReincarnation();

        void NewIntelligentCreature(S::NewIntelligentCreature *p);

        void UpdateIntelligentCreatureList(S::UpdateIntelligentCreatureList *p);

        void IntelligentCreatureEnableRename(S::IntelligentCreatureEnableRename *p);

        void IntelligentCreaturePickup(S::IntelligentCreaturePickup *p);

        void FriendUpdate(S::FriendUpdate *p);

        void LoverUpdate(S::LoverUpdate *p);

        void MentorUpdate(S::MentorUpdate *p);

        void GameShopUpdate(S::GameShopInfo *p);

        void GameShopStock(S::GameShopStock *p);
    public:
        void AddItem(UserItem *item);
        static void Bind(UserItem *item);

        static void BindQuest(ClientQuestProgress *quest);

        Color *GradeNameColor(ItemGrade grade);

        void DisposeItemLabel();
        void DisposeMailLabel();
        void DisposeMemoLabel();
        void DisposeGuildBuffLabel();

        MirControl *NameInfoLabel(UserItem *item, bool inspect = false, bool hideDura = false);
        MirControl *AttackInfoLabel(UserItem *item, bool Inspect = false, bool hideAdded = false);
        MirControl *DefenceInfoLabel(UserItem *item, bool Inspect = false, bool hideAdded = false);
        MirControl *WeightInfoLabel(UserItem *item, bool Inspect = false);
        MirControl *AwakeInfoLabel(UserItem *item, bool Inspect = false);
        MirControl *SocketInfoLabel(UserItem *item, bool Inspect = false);
        MirControl *NeedInfoLabel(UserItem *item, bool Inspect = false);
        MirControl *BindInfoLabel(UserItem *item, bool Inspect = false, bool hideAdded = false);
        MirControl *OverlapInfoLabel(UserItem *item, bool Inspect = false);
        MirControl *StoryInfoLabel(UserItem *item, bool Inspect = false);

        void CreateItemLabel(UserItem *item, bool inspect = false, bool hideDura = false, bool hideAdded = false);
        void CreateMailLabel(ClientMail *mail);
        void CreateMemoLabel(ClientFriend *friend_Keyword);

        static ItemInfo *GetInfo(int index);

        std::string GetUserName(unsigned int id);

    public:
        class UserId
        {
        public:
            long long Id = 0;
            std::string UserName = "";
        };

    public:
        class OutPutMessage
        {
        public:
            std::string Message;
            long long ExpireTime = 0;
            OutputMessageType Type = static_cast<OutputMessageType>(0);
        };

    public:
        void Rankings(S::Rankings *p);

        void Opendoor(S::Opendoor *p);

    private:
        void RentedItems(S::GetRentedItems *p);

        void ItemRentalRequest(S::ItemRentalRequest *p);

        void ItemRentalFee(S::ItemRentalFee *p);

        void ItemRentalPeriod(S::ItemRentalPeriod *p);

        void DepositRentalItem(S::DepositRentalItem *p);

        void RetrieveRentalItem(S::RetrieveRentalItem *p);

        void UpdateRentalItem(S::UpdateRentalItem *p);

        void CancelItemRental(S::CancelItemRental *p);

        void ItemRentalLock(S::ItemRentalLock *p);

        void ItemRentalPartnerLock(S::ItemRentalPartnerLock *p);

        void CanConfirmItemRental(S::CanConfirmItemRental *p);

        void ConfirmItemRental(S::ConfirmItemRental *p);

        void OpenBrowser(S::OpenBrowser *p);

    public:
        void PlaySound(S::PlaySound *p);
    private:
        void SetTimer(S::SetTimer *p);

        void ExpireTimer(S::ExpireTimer *p);

    public:
        void ShowNotice(S::UpdateNotice *p);

        #pragma region Disposable

    protected:
        void Dispose(bool disposing) override;

        #pragma endregion

    };

    class MapControl final : public MirControl
    {
    public:
        static UserObject *getUser();
        static void setUser(UserObject *value);

        static std::vector<MapObject*> Objects;

        static constexpr int CellWidth = 48;
        static constexpr int CellHeight = 32;

        static int OffSetX;
        static int OffSetY;

        static int ViewRangeX;
        static int ViewRangeY;



        static Point *getMapLocation();

        static MouseButtons *MapButtons;
        static Point *MouseLocation;
        static long long InputDelay;
        static long long NextAction;

        std::vector<std::vector<CellInfo*>> M2CellInfo;
        std::vector<Door*> Doors = std::vector<Door*>();
        int Width = 0, Height = 0;

        std::string FileName = std::string::Empty;
        std::string Title = std::string::Empty;
        unsigned short MiniMap = 0, BigMap = 0, Music = 0, SetMusic = 0;
        LightSetting Lights = static_cast<LightSetting>(0);
        bool Lightning = false, Fire = false;
        unsigned char MapDarkLight = 0;
        long long LightningTime = 0, FireTime = 0;

        bool FloorValid = false, LightsValid = false;

        long long OutputDelay = 0;

    private:
        static bool _awakeningAction;
    public:
        static bool getAwakeningAction();
        static void setAwakeningAction(bool value);

    private:
        static bool _autoRun;
    public:
        static bool getAutoRun();
        static void setAutoRun(bool value);

        static bool AutoHit;

        int AnimationCount = 0;

        static std::vector<Effect*> Effects;

        MapControl();

        void LoadMap();


        void Process();

        static MapObject *GetObject(unsigned int targetID);

        void Draw() override;

    protected:
        void CreateTexture() override;
        void DrawControl() override;

    private:
        void DrawFloor();

        void DrawBackground();

        void DrawObjects();

        Color *GetBlindLight(Color *light);

        void DrawLights(LightSetting setting);

        static void OnMouseClick(std::any sender, EventArgs *e);

        static void OnMouseDown(std::any sender, MouseEventArgs *e);

        void CheckInput();

        void UseMagic(ClientMagic *magic);

    public:
        static MirDirection MouseDirection(float ratio = 45.0F); //22.5 = 16

        static int Direction16(Point *source, Point *destination);

        static double Distance(PointF *p1, PointF *p2);

    private:
        bool EmptyCell(Point *p);

        bool CanWalk(MirDirection dir);

        bool CheckDoorOpen(Point *p);


        bool CanRun(MirDirection dir);

        bool CanRideAttack();

    public:
        bool CanFish(MirDirection dir);

        bool CanFly(Point *target);


        bool ValidPoint(Point *p);
        bool HasTarget(Point *p);
        bool CanHalfMoon(Point *p, MirDirection d);
        bool CanCrossHalfMoon(Point *p);

        #pragma region Disposable

    protected:
        void Dispose(bool disposing) override;

        #pragma endregion



    public:
        void RemoveObject(MapObject *ob);
        void AddObject(MapObject *ob);
        MapObject *FindObject(unsigned int ObjectID, int x, int y);
        void SortObject(MapObject *ob);

        Door *GetDoor(unsigned char Index);
        void Processdoors();
        void OpenDoor(unsigned char Index, bool closed);
    };
}

